﻿using System.Web.Configuration;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Marbles.Core.Web.Resources;
using Marbles.Core.Web.State;

namespace Marbles.Core.Web.MVC.Views
{
    public abstract class ViewBase : Marbles.Core.Web.Templates.Page
    {

        public string ViewStateKey
        {
            get
            {
                HtmlInputHidden field = this.Form.FindControl("__VSKEY") as HtmlInputHidden;
                if (field != null) { return field.Value; }
                if (Request.Params["__VSKEY"] != null) { return Request.Params["__VSKEY"]; }
                return string.Empty;
            }
        }
        public bool IsAuthenticated { get { return this.User.Identity.IsAuthenticated; } }
        public string Username { get { string[] args = this.User.Identity.Name.Split('\\'); if (args.Length == 1) { return args[0]; } return args[1]; } }
        public string AuthenticationMethod { get { return this.User.Identity.AuthenticationType; } }

        public bool IsHeaderMetaTagRegistered(string key)
        {
            HtmlMeta link = this.Header.FindControl(key) as HtmlMeta;
            return (link != null);
        }

        public void RegisterHeaderMetaTag(string key, string HttpEquiv, string Content, string Name)
        {
            HtmlMeta link = new HtmlMeta();
            link.ID = key;
            link.HttpEquiv = HttpEquiv;
            link.Name = Name;
            link.Content = Content;
            this.Header.Controls.Add(link);
        }

        public void RegisterHeaderMetaTag(string key, string HttpEquiv, string Content)
        {
            HtmlMeta link = new HtmlMeta();
            link.ID = key;
            link.HttpEquiv = HttpEquiv;
            link.Content = Content;
            this.Header.Controls.Add(link);
        }

        public bool IsHeaderScriptIncludeRegistered(string key)
        {
            return IsLiteralControlRegistered(key);
        }

        public bool IsHeaderCSSIncludeRegistered(string key)
        {
            HtmlLink link = this.Header.FindControl(key) as HtmlLink;
            return (link != null);
        }

        public void RegisterHeaderCSSInclude(string key, string url)
        {
            HtmlLink link = new HtmlLink();
            link.ID = key;
            link.Href = url;
            link.Attributes.Add("type", "text/css");
            link.Attributes.Add("rel", "stylesheet");
            this.Header.Controls.Add(link);
        }

        public void RegisterHeaderScriptInclude(string key, string url)
        {
            RegisterLiteralControl(key, string.Format("<script language=\"javascript\" type=\"text/javascript\" src=\"{0}\" ></script>", url), true);
        }

        internal void RegisterLiteralControl(string key, string value, bool placeinheader)
        {
            LiteralControl link = new LiteralControl();
            link.ID = key;
            link.Text = value;
            if (placeinheader) { this.Header.Controls.Add(link); } else { this.Form.Controls.Add(link); }
        }

        internal bool IsLiteralControlRegistered(string key)
        {
            LiteralControl link = this.Header.FindControl(key) as LiteralControl;
            return (link != null);
        }


        protected override void OnPreInit(EventArgs e)
        {
            string themeName = WebConfigurationManager.AppSettings["Marbles.SiteTheme"];
            string defaultTitle = WebConfigurationManager.AppSettings["Marbles.DefaultTitle"];
            if ((themeName != null) && (themeName != string.Empty)) { this.Theme = themeName; }
            if ((defaultTitle != null) && (defaultTitle != string.Empty)) { this.Title = defaultTitle; }
            base.OnPreInit(e);
        }

        protected override void OnInit(EventArgs e)
        {
            this.Form.ID = "ViewForm";
            AddViewStateKey();
        }

        private void AddViewStateKey()
        {
            HtmlInputHidden field = new HtmlInputHidden();
            field.ID = "__VSKEY";

            if (Request.Params["__VSKEY"] != null)
            {
                field.Value = Request.Params["__VSKEY"];
            }
            else
            {
                field.Value = System.Guid.NewGuid().ToString();
            }

            this.Form.Controls.Add(field);

        }

        protected override void SavePageStateToPersistenceMedium(object state)
        {
            IStatePersistanceManager mgr = null;
            string viewstatemgr = "inline";
            if (WebConfigurationManager.AppSettings["Marbles.ViewStateManager"] != null) { viewstatemgr = WebConfigurationManager.AppSettings["Marbles.ViewStateManager"]; }

            switch (viewstatemgr)
            {
                case "inline":
                    base.SavePageStateToPersistenceMedium(state); return;
                case "compressedinline":
                    mgr = new CompressedStatePersistanceManager(Marbles.Core.Helpers.CompressionMethod.Zip);
                    break;
                case "encryptedinline":
                    mgr = new EncryptedStatePersistanceManager(Marbles.Core.Helpers.EncryptionProvider.TripleDES);
                    break;
                case "sessionstate":
                    mgr = new SessionStatePersistanceManager();
                    break;
                case "sql":
                    mgr = new SqlStatePersistanceManager("ViewState");
                    break;
                case "compressedsql":
                    mgr = new SqlStatePersistanceManager("ViewState", Marbles.Core.Helpers.CompressionMethod.Zip);
                    break;
                case "compressedsessionstate":
                    mgr = new SessionStatePersistanceManager(Marbles.Core.Helpers.CompressionMethod.Zip);
                    break;
            }

            if (mgr != null) { mgr.SavePageStateToPersistenceMedium(state, this); }
        }

        protected override object LoadPageStateFromPersistenceMedium()
        {
            IStatePersistanceManager mgr = null;
            string viewstatemgr = "inline";
            if (WebConfigurationManager.AppSettings["Marbles.ViewStateManager"] != null) { viewstatemgr = WebConfigurationManager.AppSettings["Marbles.ViewStateManager"]; }

            switch (viewstatemgr)
            {
                case "inline":
                    return base.LoadPageStateFromPersistenceMedium();
                case "compressedinline":
                    mgr = new CompressedStatePersistanceManager(Marbles.Core.Helpers.CompressionMethod.Zip);
                    break;
                case "encryptedinline":
                    mgr = new EncryptedStatePersistanceManager(Marbles.Core.Helpers.EncryptionProvider.TripleDES);
                    break;
                case "sessionstate":
                    mgr = new SessionStatePersistanceManager();
                    break;
                case "sql":
                    mgr = new SqlStatePersistanceManager("ViewState");
                    break;
                case "compressedsql":
                    mgr = new SqlStatePersistanceManager("ViewState", Marbles.Core.Helpers.CompressionMethod.Zip);
                    break;
                case "compressedsessionstate":
                    mgr = new SessionStatePersistanceManager(Marbles.Core.Helpers.CompressionMethod.Zip);
                    break;
            }

            if (mgr != null) { return mgr.LoadPageStateFromPersistenceMedium(this); }
            return null;
        }

        public void RegisterMarblesApplicationScript()
        {
            if (!IsHeaderScriptIncludeRegistered("MarblesApplication"))
            {
                MarblesScriptLibraryResource res = new MarblesScriptLibraryResource();
                RegisterHeaderScriptInclude("MarblesApplication", res.ApplicationLibraryResourceUrl);

                if (!Page.ClientScript.IsClientScriptBlockRegistered("MarblesApplicationInit"))
                {
                    Page.ClientScript.RegisterClientScriptBlock(typeof(System.String), "MarblesApplicationInit", res.GetMarblesApplicationInitialiser(), false);
                }
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            if (!IsLiteralControlRegistered("Base")) { RegisterLiteralControl("Base", "<base target=\"_self\" />", true); }
            RegisterMarblesApplicationScript();

            base.OnLoad(e);
        }
    }
}
